The overloaded shift operator syntax is strange at first sight, but it quickly grows on you. However syntax is just syntax; the real issues are deeper. Printf is arguably not broken, and scanf is perhaps livable despite being error prone, however both are limited with respect to what C++ I/O can do. C++ I/O (left/right shift) is, relative to C (printf/scanf):
* type safe -- type of object being I/O'd is known statically by the compiler rather than via dynamically tested '%' fields
* less error prone -- redundant info has greater chance to get things wrong C++ I/O has no redundant '%' tokens to get right
* faster -- printf is basically an 'interpreter' of a tiny language whose constructs mainly include '%' fields. the proper low-level routine is chosen at runtime based on these fields. C++ I/O picks these routines statically based on actual types of the args
* extensible -- perhaps most important of all, the C++ I/O mechanism is extensible to new user-defined data types (imagine the chaos if everyone was simultaneously adding new incompatible '%' fields to printf and scanf?!). Remember: we want to make user-defined types (classes) look and act like 'built-in' types.
* subclassable -- ostream and istream (the C++ replacements for FILE*) are real classes, and hence subclassableÔ£ømeans you can have other user defined things that look and act like streams, yet that do whatever strange and wonderful things you want. You automatically get to use the zillions of lines of I/O code written by users you don't even know, and they don't need to know about your 'extended stream' class. Ex: you can have a 'stream' that writes to a memory area (incore formatting provided by the standard class 'strstream'), or you could have it use the stdio buffers, or [you name it...]